using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XML;

public class LevelManager : MonoBehaviour {

    public string fileName;
    public string fileNameDecors;
    public Vector3 startPos;
    public GameObject baseTile;

    private List<EnemyCurve> _curves = new List<EnemyCurve>();
    private List<Enemy> _listEnemys = new List<Enemy>();

	private float timeStar3;
	private float timeStar2;
	private float timeStar1;
	
	private Transform _enemyParent;
    private float _timeStart = 0;
    private string nameLevelNext = "";

	// Use this for initialization
	void Awake () {

        DeserializeLevel(fileName);
        DeserializeDecors(fileNameDecors);
	}
	
	void Start()
	{
		_enemyParent = GameObject.Find("Enemys").transform;

        int nbChild = _enemyParent.GetChildCount();
        for(int i = 0; i < nbChild; ++i)
        {
            _listEnemys.Add(_enemyParent.GetChild(i).GetComponent<Enemy>());

        }

        _timeStart = Time.time;
        
	}

    void Update()
	{
		if (Input.GetKeyDown(KeyCode.R) || Input.GetKeyDown(KeyCode.Joystick1Button2))
            Application.LoadLevel(Application.loadedLevel);
    }


    //End of stage
    public void EndStage(bool win)
	{
		//End Level		
        int nbStar = 0;
        float time = Time.time - _timeStart;



        if (time <= timeStar3 && win)
		{
            nbStar = 3;
		}
        else if (time <= timeStar2 && win)
		{
            nbStar = 2;
		}
        else if (time <= timeStar1 && win)
		{
            nbStar = 1;
		}


        PlayerManager.Instance.SetLevelResult(Application.loadedLevelName, nbStar, time, timeStar3, timeStar2, timeStar1, nameLevelNext);
        Application.LoadLevel("WinMenu");
		
	}
	
	//Test if all mob are dead
	public bool IsStageClear()
	{
		int nbChild = _enemyParent.GetChildCount();
		
        for(int i = 0; i < nbChild; ++i)
        {
            if (_enemyParent.GetChild(i).GetComponent<Enemy>().Alive)
                return false;
        }

		return true;
	}
	

    //Get Enemys at distance
    public List<Enemy> GetEnemyAtDistance(Vector3 pos, float distance)
    {
        List<Enemy> enemyNear = new List<Enemy>();

        foreach (Enemy enemy in _listEnemys)
        {
            Vector3 posEnemy = new Vector3(enemy.transform.position.x, pos.y, enemy.transform.position.z);

            if (Vector3.Distance(pos, posEnemy) < distance)
            {
                enemyNear.Add(enemy);
            }
        }
        return enemyNear;
    }

    //Load Level
    void DeserializeLevel(string name)
    {
        TextAsset txt = (TextAsset)Resources.Load("XML/" + name);
        InStream stream = new InStream(txt.text);

        string type = "";
        string nameCurve;
        int nbPop;
        float speed;
        Vector3 pos;

		stream.Content("TimeStar3", out timeStar3);
		stream.Content("TimeStar2", out timeStar2);
		stream.Content("TimeStar1", out timeStar1);

        stream.Content("NextLevel", out nameLevelNext);

        stream.List("Curve", delegate(InStream stream2)
        {
            stream2.Attribute("Type", out type)
                .Attribute("Name", out nameCurve)
                .Attribute("Speed", out speed)
                .Attribute("NbPop", out nbPop);

            //Creation of the curve
            GameObject curve = new GameObject();
            curve.name = nameCurve;
            curve.transform.position = Vector3.zero;

            EnemyCurve enemyCurve = curve.AddComponent(typeof(EnemyCurve)) as EnemyCurve;
            enemyCurve.nbEnemyPop = nbPop;
            enemyCurve.durationCurve = speed;
            enemyCurve.SetTypeByName(type);

            _curves.Add(enemyCurve);

            bool first = true;
            GameObject firstGo = null;
            int nb = 0;
            stream2.List("Point", delegate(InStream stream3)
            {
                //Creation of all points
                stream3.Attribute("Name", out nameCurve)
                    .Content("Position", out pos);

                GameObject point = new GameObject();
                point.transform.parent = curve.transform;
                point.name = nameCurve;
                point.transform.position = pos;
                nb++;

                if(first)
                {
                    firstGo = point;
                    first = false;
                }

            });

            GameObject newPoint = new GameObject();
            newPoint.transform.parent = curve.transform;
            newPoint.name = nb.ToString();
            newPoint.transform.position = firstGo.transform.position;

            enemyCurve.Launch();
        });
    }

    //Load Level
    void DeserializeDecors(string name)
    {
        if (name == "")
            return;

        TextAsset txt = (TextAsset)Resources.Load("XML/" + name);
        InStream stream = new InStream(txt.text);

        string type = "";
        Vector3 pos;

        GameObject go = new GameObject();
        go.name = "Tiles";
        go.transform.position = Vector3.zero;

        stream.List("Tile", delegate(InStream stream2)
        {
            stream2.Content("Type", out type);
            stream2.Content("pos", out pos);

            GameObject newTile = Instantiate(baseTile) as GameObject;
            newTile.transform.position = pos;
            newTile.transform.parent = go.transform;

            if (type == Const.TYPE_TILE.BUSH.ToString())
            {
                newTile.transform.position = new Vector3(pos.x, 2, pos.z);
                newTile.GetComponent<Tile>().SetType(Const.TYPE_TILE.BUSH);
            }
            else
            {
                newTile.transform.position = new Vector3(pos.x, - 1, pos.z);
                newTile.layer = Const.LAYER_GROUND;
            }

        });
    }

}
